/*
 *Copyright (c) [2019-2020]  C2comm, Inc.  All rights reserved.
 *
 *This program is free software; you can redistribute it and/or
 *modify it under the terms of the GNU General Public License
 *as published by the Free Software Foundation; either version 2
 *of the License, or (at your option) any later version.
 *
 *This program is distributed in the hope that it will be useful,
 *but WITHOUT ANY WARRANTY; without even the implied warranty of
 *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *GNU General Public License for more details.
 *
 *You should have received a copy of the GNU General Public License
 *along with this program; If not, see <https://www.gnu.org/licenses/>
 */
/*
 *Vendor: C2comm
 *Version: 1.0
 *Filename:SyncCompute.v
 *Target Device: Altera
 *Author : 刘晓骏
*/

module SyncCompute(
    input  wire         SYS2CORE_clk,
    input  wire         SYS2CORE_rst_n,
    input  wire [336:0] CONF2CORE_cm_static_conf,
    input  wire [ 27:0] CONF2CORE_dbg_conf,//add by lxj 20200526
    
    input  wire [ 19:0] G_local_clk,
    input  wire [  5:0] G_Integration_Cycle,

    input  wire         G_pcf_des_wr,
    input  wire [ 90:0] G_pcf_des,

    output reg  [ 19:0] SCP2LCC_clock_corr,

    output wire         SCP2CD_sync_des_valid,
    output wire [ 17:0] SCP2CD_sync_des,

    output wire [298:0] CORE2MON_cm_state
);
/*//////////////////////////////////////////////////////////
                    中间变量声明区域
*///////////////////////////////////////////////////////////
//本模块中所有中间变量(wire/reg/parameter)在此集中声明 
reg [19:0] start_acceptance_window;
reg [19:0] end_acceptance_window;

wire        sync_judge;


wire        intype_valid;
wire        best_judge;

wire [3:0]  curr_bin_memb_num;
reg  [3:0]  best_bin_memb_num;

wire [19:0] user_dbg_corr;

localparam PCF_CS        = 2'd0,
           PCF_CA        = 2'd1,
           PCF_IN        = 2'd2;
/*//////////////////////////////////////////////////////////
                      其他信号处理
*///////////////////////////////////////////////////////////
assign CORE2MON_cm_state = {47'b0,SCP2LCC_clock_corr,232'b0};

/*//////////////////////////////////////////////////////////
                同步判定(SyncJudge)
*///////////////////////////////////////////////////////////

assign intype_valid  = G_pcf_des_wr & (G_pcf_des[17:16] == PCF_IN);


assign sync_judge = (G_pcf_des[ 7: 2] == G_Integration_Cycle) &
                    (G_pcf_des[37:18] >= start_acceptance_window) &
                    (G_pcf_des[37:18] <= end_acceptance_window);
                    

assign best_judge = (sync_judge == 1'b1) & 
                    ((best_bin_memb_num == 4'b0) | (best_bin_memb_num < curr_bin_memb_num));
                        

assign SCP2CD_sync_des_valid = (intype_valid == 1'b1) & 
                               ((best_judge == 1'b1) | (sync_judge == 1'b0));
assign SCP2CD_sync_des       = {sync_judge,
                                G_pcf_des[42:38],
                                curr_bin_memb_num,
                                G_pcf_des[15:8]};


always @(posedge SYS2CORE_clk) begin
   
    start_acceptance_window <= CONF2CORE_cm_static_conf[79:60] - CONF2CORE_cm_static_conf[274:256];    
  
    end_acceptance_window   <= CONF2CORE_cm_static_conf[79:60] + CONF2CORE_cm_static_conf[274:256];
end


assign curr_bin_memb_num = G_pcf_des[15] + G_pcf_des[14] + 
                           G_pcf_des[13] + G_pcf_des[12] + 
                           G_pcf_des[11] + G_pcf_des[10] + 
                           G_pcf_des[ 9] + G_pcf_des[ 8];
                           
                           

assign user_dbg_corr = (G_Integration_Cycle == CONF2CORE_dbg_conf[25:20]) ? CONF2CORE_dbg_conf[19:0] : 20'b0;
	

always @(posedge SYS2CORE_clk or negedge SYS2CORE_rst_n) begin
    if(!SYS2CORE_rst_n) begin
        best_bin_memb_num  <= 4'b0;
        SCP2LCC_clock_corr <= 20'b0;
    end
    else begin
        if((G_local_clk<start_acceptance_window)||(G_local_clk>=CONF2CORE_cm_static_conf[19:0])) begin
       
            best_bin_memb_num  <= 4'b0;
            SCP2LCC_clock_corr <= 20'b0;
        end
        else if((G_local_clk <= end_acceptance_window) && 
                (intype_valid == 1'b1) && 
                (best_judge == 1'b1))begin
   
               best_bin_memb_num  <= curr_bin_memb_num;
               SCP2LCC_clock_corr <= CONF2CORE_cm_static_conf[79:60] - G_pcf_des[37:18] + user_dbg_corr;//add by lxj 20200526
        end
        else begin
            best_bin_memb_num  <= best_bin_memb_num;
            SCP2LCC_clock_corr <= SCP2LCC_clock_corr;
        end
    end
end


/*//////////////////////////////////////////////////////////
                   IP调用区域
*///////////////////////////////////////////////////////////
//本模块调用的所有IP在该区域实例化
//例如fifo/ram/grant之类的IP.... 
endmodule
/*
SyncCompute SyncCompute_inst(
    .SYS2CORE_clk(),
    .SYS2CORE_rst_n(),
    .CONF2CORE_cm_static_conf(),
    .G_local_clk(),
    .G_Integration_Cycle(),

    .G_pcf_des_wr(),
    .G_pcf_des(),

    .SCP2LCC_clock_corr(),

    .SCP2CD_sync_des_valid(),
    .SCP2CD_sync_des(),

    .CORE2MON_cm_state()
);
*/